package com.lbssoft.gpsbd.datalink;

import com.alibaba.fastjson.JSON;
import com.lbssoft.datalink.model.Command;
import com.lbssoft.datalink.util.Log;
import com.lbssoft.gpsbd.common.MessageUtil;
import com.lbssoft.gpsbd.common.Utils;
import com.lbssoft.gpsbd.common.WebSocketMessage;
import com.lbssoft.gpsbd.dao.DeviceMapper;
import com.lbssoft.gpsbd.dao.EventMapper;
import com.lbssoft.gpsbd.dao.GeofenceMapper;
import com.lbssoft.gpsbd.dao.PositionMapper;
import com.lbssoft.gpsbd.model.*;
import com.lbssoft.gpsbd.model.vo.DeviceStatus;
import com.lbssoft.gpsbd.service.CommandRecordService;
import com.lbssoft.gpsbd.service.PositionService;
import org.springframework.context.ApplicationContext;

import java.util.*;

public class DataManager {
	private static ApplicationContext applicationContext;
	PositionMapper positionMapper =applicationContext.getBean(PositionMapper.class);
	DeviceMapper deviceMapper =applicationContext.getBean(DeviceMapper.class);
	EventMapper eventMapper = applicationContext.getBean(EventMapper.class);
	//DeviceService deviceService = applicationContext.getBean(DeviceService.class);
	CommandRecordService  commandRecordService= applicationContext.getBean(CommandRecordService.class);
	PositionService positionService = applicationContext.getBean(PositionService.class);
	GeofenceMapper geofenceMapper =applicationContext.getBean(GeofenceMapper.class);

   
 
    Map<String,Object> position;
	public DataManager(){
		init();
	}
	
	public void init(){
		List<Position> lastPositions= positionMapper.getLastPositions();
		for(int i=0;i<lastPositions.size();i++){
			Context.positions.put(lastPositions.get(i).getDeviceId(), lastPositions.get(i));
		}
		
		Collection<Device> devices = deviceMapper.getAllDevices();

		 for (Device device : devices) {
			 Context.deviceByUuid.put(device.getUuid(), device);
			// Context.states.put(device.getId(), (Map) JSONObject.parse(device.getState()));

		 }

		Collection<Geofence> geofences = geofenceMapper.getAllGeofences();
		for (Geofence geofence : geofences) {
			Context.geofenceByUuid.put(geofence.getUuid(), geofence);

		}

		 
		 Collection<DevicePermission> permis = deviceMapper.getDevicePermissions();
		
		 for (DevicePermission permission : permis) {
			 Context.userByDevice.put(permission.getDeviceId(), permission.getUserId());

         }

	}
	
	

	/**
	 * 插入设备位置 并更新最后位置点
	 * @param p
	 */
	public  void updateLastPosition(com.lbssoft.datalink.model.Position p) {
		positionService.updateLatestPosition(p);
	}

	/**
	 * 更新设备状态
	 */
	public void updateStatus(int status,String uuid){
		Device dev = Context.deviceByUuid.get(uuid);
		if(dev==null){
			Log.info("未知设备："+uuid);
			return;
		}
		
		DeviceStatus deviceStatus = new DeviceStatus();
		deviceStatus.setDeviceId(dev.getId());
		deviceStatus.setId(dev.getId());
		deviceStatus.setName(dev.getName());
		deviceStatus.setStatus(status==-1?0:status);
		deviceStatus.setTime(new Date());

		Collection<DeviceStatus> deviceMsgs = new ArrayList<DeviceStatus>();
		deviceMsgs.add(deviceStatus);
		SocketMsg socketMsg = new SocketMsg("devices",deviceMsgs);
		
		//deviceMapper.updateStatus(status==-1?0:status,dev.getId());
		WebSocketMessage.send(socketMsg,Context.userByDevice.get(dev.getId()));
	
	}

	/**
	 * 推送通知
	 * @param status
	 * @param dev
     */
	public void pushMessage(int status,Device dev){
		DeviceStatus deviceStatus = new DeviceStatus();
		deviceStatus.setDeviceId(dev.getId());
		deviceStatus.setId(dev.getId());
		deviceStatus.setName(dev.getName());
		deviceStatus.setStatus(status==-1?0:status);
		deviceStatus.setTime(new Date());

		Collection<DeviceStatus> deviceMsgs = new ArrayList<DeviceStatus>();
		deviceMsgs.add(deviceStatus);
		SocketMsg socketMsg = new SocketMsg("devices",deviceMsgs);
		long userId = Context.userByDevice.get(dev.getId());
		WebSocketMessage.send(socketMsg,userId);
		String msg = "未知";
		switch (status){
			case -1:
				msg="链路超时";
				break;
			case 0:
				msg="离线";
				break;
			case 1:
				msg="上线";
				break;
			case 2:
				msg="进入围栏";
				break;
			case 3:
				msg="离开围栏";
				break;
			case 4:
				msg="超速";
				break;
			case 9:
				msg="设备报警";
				break;

		}

		MessageUtil.sendNotificationWithAlias(dev.getName(),msg,String.valueOf(userId),new HashMap<String, String>(),"defalut");
	}
	
	public void addEvent(com.lbssoft.datalink.model.Event ev){
		Device dev = Context.deviceByUuid.get(ev.getDeviceUUID());
		if(dev==null){
			Log.info("未知设备："+ev.getUniqueId());
			return;
		}
		Event event = new Event();
		String address = "";
		event.setDeviceId(dev.getId());
		event.setType(ev.getStatus()==-1?0:ev.getStatus());
		event.setAttributes("{}");
		//围栏消息
		if(ev.getStatus()==2||ev.getStatus()==3){
			Geofence geofence = Context.geofenceByUuid.get(ev.getGeofenceUUID());
			if(geofence!=null){
				event.setGeofenceId((int)geofence.getId());
				Log.info("围栏信息"+ JSON.toJSONString(geofence));
			}else{
				Log.info("未知围栏"+ev.getGeofenceUUID());
			}

		}else if(ev.getStatus() == 1 || ev.getStatus() == 0 || ev.getStatus() == -1){
			deviceMapper.updateStatus(ev.getStatus()==-1?0:ev.getStatus(),dev.getId());
		}
		Position position = positionMapper.getPositionByDeviceId(dev.getId());
		try {
			if(position!=null){
				address = Utils.BaiduGeocoder(position.getLongitude(),position.getLatitude());
				event.setPositionId(position.getId());
				event.setAddress(address);
			}

		}catch (Exception e){

		}

		eventMapper.addEvent(event);
		pushMessage(ev.getStatus(),dev);
	}

	public void addAlarm(Event event){
		eventMapper.addEvent(event);
		DeviceStatus deviceStatus = new DeviceStatus();
		deviceStatus.setDeviceId(event.getDeviceId());
		deviceStatus.setId(event.getDeviceId());
		deviceStatus.setStatus(event.getType());
		deviceStatus.setAttributes(event.getAttributes());
		deviceStatus.setTime(new Date());

		Collection<DeviceStatus> deviceMsgs = new ArrayList<DeviceStatus>();
		deviceMsgs.add(deviceStatus);
		SocketMsg socketMsg = new SocketMsg("devices",deviceMsgs);

		WebSocketMessage.send(socketMsg,Context.userByDevice.get(event.getDeviceId()));
		
	}

	public void updateCommandRecord(Command command ){
		Device dev = Context.deviceByUuid.get(command.getDeviceUUID());
		if(dev==null){
			Log.info("未知设备："+command.getUniqueId());
			return;
		}
		command.setDeviceId(dev.getId());
		commandRecordService.handlerCommandResult(command);

	}



	
	public static void setApplicationContext(ApplicationContext context) {
	    applicationContext = context;
	  }
}
